package com.piece.core.mongo.context;

import com.piece.core.framework.util.math.SequenceUtil;
import com.piece.core.log.client.dto.AuditLogDTO;
import com.piece.core.log.client.AuditLogService;
import com.piece.core.mongo.entity.MongoAuditLog;
import com.piece.core.mongo.service.MongoAuditLogService;
import com.piece.core.framework.support.bootstrap.DataTable;
import com.piece.core.framework.support.bootstrap.QueryTable;
import com.piece.core.framework.util.object.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 审计日志实现类-mongo
 */
@Slf4j
@Component("audit_log_service_mongo")
@ConditionalOnProperty(name = "spring.log.type", havingValue = "mongo")
public class AuditLogServiceMongoImpl implements AuditLogService {

    @Resource
    private MongoAuditLogService mongoAuditLogService;

    @Async
    @Override
    public AuditLogDTO save(AuditLogDTO auditLog) {
        try {
            MongoAuditLog operaLog = convertToDb(auditLog);
            operaLog.setLogId(SequenceUtil.uuid());
            operaLog = mongoAuditLogService.insert(operaLog);
            auditLog.setLogId(operaLog.getLogId());
            return auditLog;
        } catch (Exception e) {
            log.error("插入审计日志异常：{}", e.getMessage());
        }

        return null;
    }

    @Async
    @Override
    public void delete(AuditLogDTO auditLog) {
        mongoAuditLogService.delete(auditLog.getLogId());
    }

    @Async
    @Override
    public void deleteByClientId(String clientId) {
        mongoAuditLogService.deleteByClientId(clientId);
    }

    @Async
    @Override
    public void clear() {
        mongoAuditLogService.deleteAll();
    }

    @Override
    public List<AuditLogDTO> findByCondition(Map<String, Object> param) {
        QueryTable queryTable = new QueryTable();
        queryTable.setParams(param);
        List<MongoAuditLog> operaLogs = mongoAuditLogService.findList(queryTable);
        return operaLogs.stream().map(operaLog -> {
            AuditLogDTO auditLog = null;
            try {
                auditLog = convertToLog(operaLog);
            } catch (Exception e) {
                log.error("转换日志对象异常：{}", e.getMessage());
            } finally {
                return auditLog;
            }
        }).collect(Collectors.toList());
    }

    public DataTable<MongoAuditLog> findByCondition(QueryTable queryTable) {
        return mongoAuditLogService.findPage(queryTable);
    }

    private MongoAuditLog convertToDb(AuditLogDTO audit) {
        MongoAuditLog auditLog = new MongoAuditLog();
        BeanUtil.copyProperties(audit, auditLog);
        return auditLog;
    }

    private AuditLogDTO convertToLog(MongoAuditLog auditLog) {
        AuditLogDTO logDTO = new AuditLogDTO();
        BeanUtil.copyProperties(auditLog, logDTO);
        return logDTO;
    }
}